-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix IOperation for asynchronous using and foreach statements #37963
Conversation
ff133de
to
e2965d7
Compare
@AlekseyTs I thought I'd have something more to do for CFG, but I think I've already handled it. Thanks #Resolved |
e2965d7
to
a5f362d
Compare
@333fred for review. Thanks #Closed |
Locals: Local_1: System.String value | ||
LoopControlVariable: | ||
IVariableDeclaratorOperation (Symbol: System.String value) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'string') | ||
Initializer: | ||
null | ||
Collection: | ||
IParameterReferenceOperation: pets (OperationKind.ParameterReference, Type: System.Collections.Generic.IAsyncEnumerable<System.String>) (Syntax: 'pets') | ||
IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Collections.Generic.IAsyncEnumerable<System.String>, IsImplicit) (Syntax: 'pets') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know why this conversion is introduced? #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure. The logic in BindForEachPartsWorker always wraps the collection expression with a BoundConversion (even when the conversion is Identity).
The conversion is there in other IOperation tests for regular foreach loops (ForEachFlow_06
) so this seems correct.
Let me know if this bugs you. I can investigate further.
In reply to: 316309905 [](ancestors = 316309905)
Please add some tests with the IAsyncX interfaces missing in the compilation for both IOp and CFG generation. #Closed |
@@ -600,6 +600,10 @@ private void LogLoopStatementHeader(ILoopOperation operation, bool? isChecked = | |||
var propertyStringBuilder = new StringBuilder(); | |||
propertyStringBuilder.Append(" ("); | |||
propertyStringBuilder.Append($"{nameof(LoopKind)}.{operation.LoopKind}"); | |||
if (operation is IForEachLoopOperation foreachLoop && foreachLoop.IsAsynchronous) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreachLoop && foreachLoop.IsAsynchronous [](start = 51, length = 41)
Nit: could use recursive pattern :) #Closed
Done review pass (commit 4) #Closed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (commit 5)
@dotnet/roslyn-compiler for another review. |
<Property Name="IsAsynchronous" Type="bool"> | ||
<Comments> | ||
<summary> | ||
Whether this for using is asynchronous. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for [](start = 23, length = 3)
Remove? #Pending
@@ -4110,9 +4122,15 @@ public override IOperation VisitForEachLoop(IForEachLoopOperation operation, int | |||
|
|||
LeaveRegion(); | |||
|
|||
bool isAsynchronous = info.IsAsynchronous; | |||
var iDisposable = isAsynchronous | |||
? _compilation.GetTypeByMetadataName(WellKnownTypes.GetMetadataName(WellKnownType.System_IAsyncDisposable)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_compilation.GetTypeByMetadataName(WellKnownTypes.GetMetadataName(WellKnownType.System_IAsyncDisposable) [](start = 22, length = 104)
Should there be a CommonGetWellKnownType()
method? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -30,6 +30,8 @@ internal sealed class ForEachEnumeratorInfo | |||
// When async and needs disposal, this stores the information to await the DisposeAsync() invocation | |||
public AwaitableInfo DisposeAwaitableInfo; | |||
|
|||
public readonly bool IsAsync; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool [](start = 24, length = 4)
Minor point: Perhaps move next to NeedsDisposal
to reduce size of instance. #Resolved
@@ -3841,7 +3852,8 @@ bool isNotNullableValueType(ITypeSymbol type) | |||
|
|||
private IOperation ConvertToIDisposable(IOperation operand, ITypeSymbol iDisposable, bool isTryCast = false) | |||
{ | |||
Debug.Assert(iDisposable.SpecialType == SpecialType.System_IDisposable); | |||
Debug.Assert(iDisposable.SpecialType == SpecialType.System_IDisposable || | |||
iDisposable.Equals( _compilation.GetTypeByMetadataName(WellKnownTypes.GetMetadataName(WellKnownType.System_IAsyncDisposable)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetTypeByMetadataName [](start = 49, length = 21)
CommonGetWellKnownType()
#Resolved
Fixes #30362
IsAsynchronous
toIUsingOperation
andIForEachLoopOperation
IsAsynchronous
toForeachEnumeratorInfo
DisposeAsync()
andMoveNextAsync()
IDisposable
to beIAsyncDisposable